---
keywords:
- descriptor
- view
- access
- contract functions
- schema tool
description: The schema tool provides us with an easy way to access to smart contract functions through function descriptors, which allow you to initiate the function by calling it synchronously, or posting a request to run it asynchronously.
image: /img/logo/WASP_logo_dark.png
---
import Tabs from "@theme/Tabs"
import TabItem from "@theme/TabItem"

# Function Descriptors

The schema tool provides us with an easy way to access to smart contract functions through
_function descriptors_. These are structures that provide access to the optional params
and result maps through strict compile-time checked interfaces. They will also allow you
to initiate the function by calling it [synchronously](call.mdx), or posting a request to
run it [asynchronously](post.mdx).

The schema tool will generate a specific function descriptor for each func and view. It
will also generate an interface called ScFuncs, that can be used to create and initialize
each function descriptor. Here is the code generated for the `dividend` example
in `contract.xx`:

<Tabs defaultValue="go"
      groupId="language"
      values={[
          {label: 'Go', value: 'go'},
          {label: 'Rust', value: 'rust'},
          {label: 'TypeScript', value: 'ts'},
      ]}>

<TabItem value="go">

```go
package dividend

import "github.com/iotaledger/wasp/packages/vm/wasmlib"

type DivideCall struct {
    Func *wasmlib.ScFunc
}

type InitCall struct {
    Func   *wasmlib.ScInitFunc
    Params MutableInitParams
}

type MemberCall struct {
    Func   *wasmlib.ScFunc
    Params MutableMemberParams
}

type SetOwnerCall struct {
    Func   *wasmlib.ScFunc
    Params MutableSetOwnerParams
}

type GetFactorCall struct {
    Func    *wasmlib.ScView
    Params  MutableGetFactorParams
    Results ImmutableGetFactorResults
}

type GetOwnerCall struct {
    Func    *wasmlib.ScView
    Results ImmutableGetOwnerResults
}

type Funcs struct{}

var ScFuncs Funcs

func (sc Funcs) Divide(ctx wasmlib.ScFuncCallContext) *DivideCall {
    return &DivideCall{Func: wasmlib.NewScFunc(ctx, HScName, HFuncDivide)}
}

func (sc Funcs) Init(ctx wasmlib.ScFuncCallContext) *InitCall {
    f := &InitCall{Func: wasmlib.NewScInitFunc(ctx, HScName, HFuncInit, keyMap[:], idxMap[:])}
    f.Func.SetPtrs(&f.Params.id, nil)
    return f
}

func (sc Funcs) Member(ctx wasmlib.ScFuncCallContext) *MemberCall {
    f := &MemberCall{Func: wasmlib.NewScFunc(ctx, HScName, HFuncMember)}
    f.Func.SetPtrs(&f.Params.id, nil)
    return f
}

func (sc Funcs) SetOwner(ctx wasmlib.ScFuncCallContext) *SetOwnerCall {
    f := &SetOwnerCall{Func: wasmlib.NewScFunc(ctx, HScName, HFuncSetOwner)}
    f.Func.SetPtrs(&f.Params.id, nil)
    return f
}

func (sc Funcs) GetFactor(ctx wasmlib.ScViewCallContext) *GetFactorCall {
    f := &GetFactorCall{Func: wasmlib.NewScView(ctx, HScName, HViewGetFactor)}
    f.Func.SetPtrs(&f.Params.id, &f.Results.id)
    return f
}

func (sc Funcs) GetOwner(ctx wasmlib.ScViewCallContext) *GetOwnerCall {
    f := &GetOwnerCall{Func: wasmlib.NewScView(ctx, HScName, HViewGetOwner)}
    f.Func.SetPtrs(nil, &f.Results.id)
    return f
}
```

</TabItem>

<TabItem value="rust">

```rust
use std::ptr;

use wasmlib::*;

use crate::consts::*;
use crate::params::*;
use crate::results::*;

pub struct DivideCall {
    pub func: ScFunc,
}

pub struct InitCall {
    pub func:   ScFunc,
    pub params: MutableInitParams,
}

pub struct MemberCall {
    pub func:   ScFunc,
    pub params: MutableMemberParams,
}

pub struct SetOwnerCall {
    pub func:   ScFunc,
    pub params: MutableSetOwnerParams,
}

pub struct GetFactorCall {
    pub func:    ScView,
    pub params:  MutableGetFactorParams,
    pub results: ImmutableGetFactorResults,
}

pub struct ScFuncs {
}

impl ScFuncs {
    pub fn divide(_ctx: & dyn ScFuncCallContext) -> DivideCall {
        DivideCall {
            func: ScFunc::new(HSC_NAME, HFUNC_DIVIDE),
        }
    }
    pub fn init(_ctx: & dyn ScFuncCallContext) -> InitCall {
        let mut f = InitCall {
            func:   ScFunc::new(HSC_NAME, HFUNC_INIT),
            params: MutableInitParams { id: 0 },
        };
        f.func.set_ptrs(&mut f.params.id, ptr::null_mut());
        f
    }
    pub fn member(_ctx: & dyn ScFuncCallContext) -> MemberCall {
        let mut f = MemberCall {
            func:   ScFunc::new(HSC_NAME, HFUNC_MEMBER),
            params: MutableMemberParams { id: 0 },
        };
        f.func.set_ptrs(&mut f.params.id, ptr::null_mut());
        f
    }
    pub fn set_owner(_ctx: & dyn ScFuncCallContext) -> SetOwnerCall {
        let mut f = SetOwnerCall {
            func:   ScFunc::new(HSC_NAME, HFUNC_SET_OWNER),
            params: MutableSetOwnerParams { id: 0 },
        };
        f.func.set_ptrs(&mut f.params.id, ptr::null_mut());
        f
    }
    pub fn get_factor(_ctx: & dyn ScViewCallContext) -> GetFactorCall {
        let mut f = GetFactorCall {
            func:    ScView::new(HSC_NAME, HVIEW_GET_FACTOR),
            params:  MutableGetFactorParams { id: 0 },
            results: ImmutableGetFactorResults { id: 0 },
        };
        f.func.set_ptrs(&mut f.params.id, &mut f.results.id);
        f
    }
}
```

</TabItem>
<TabItem value="ts">

```ts
import * as wasmlib from "wasmlib"
import * as sc from "./index";

export class DivideCall {
    func: wasmlib.ScFunc = new wasmlib.ScFunc(sc.HScName, sc.HFuncDivide);
}

export class InitCall {
    func: wasmlib.ScInitFunc = new wasmlib.ScInitFunc(sc.HScName, sc.HFuncInit);
    params: sc.MutableInitParams = new sc.MutableInitParams();
}

export class MemberCall {
    func: wasmlib.ScFunc = new wasmlib.ScFunc(sc.HScName, sc.HFuncMember);
    params: sc.MutableMemberParams = new sc.MutableMemberParams();
}

export class SetOwnerCall {
    func: wasmlib.ScFunc = new wasmlib.ScFunc(sc.HScName, sc.HFuncSetOwner);
    params: sc.MutableSetOwnerParams = new sc.MutableSetOwnerParams();
}

export class GetFactorCall {
    func: wasmlib.ScView = new wasmlib.ScView(sc.HScName, sc.HViewGetFactor);
    params: sc.MutableGetFactorParams = new sc.MutableGetFactorParams();
    results: sc.ImmutableGetFactorResults = new sc.ImmutableGetFactorResults();
}

export class GetOwnerCall {
    func: wasmlib.ScView = new wasmlib.ScView(sc.HScName, sc.HViewGetOwner);
    results: sc.ImmutableGetOwnerResults = new sc.ImmutableGetOwnerResults();
}

export class ScFuncs {
    static divide(ctx: wasmlib.ScFuncCallContext): DivideCall {
        let f = new DivideCall();
        return f;
    }

    static init(ctx: wasmlib.ScFuncCallContext): InitCall {
        let f = new InitCall();
        f.func.setPtrs(f.params, null);
        return f;
    }

    static member(ctx: wasmlib.ScFuncCallContext): MemberCall {
        let f = new MemberCall();
        f.func.setPtrs(f.params, null);
        return f;
    }

    static setOwner(ctx: wasmlib.ScFuncCallContext): SetOwnerCall {
        let f = new SetOwnerCall();
        f.func.setPtrs(f.params, null);
        return f;
    }

    static getFactor(ctx: wasmlib.ScViewCallContext): GetFactorCall {
        let f = new GetFactorCall();
        f.func.setPtrs(f.params, f.results);
        return f;
    }

    static getOwner(ctx: wasmlib.ScViewCallContext): GetOwnerCall {
        let f = new GetOwnerCall();
        f.func.setPtrs(null, f.results);
        return f;
    }
}
```

</TabItem>
</Tabs>

As you can see a struct has been generated for each of the funcs and views. The structs
only provide access to `params` or `results` when these are specified for the function.
Each struct has a `func` member that can be used to initiate the function call in certain
ways. The `func` member will be of type ScFunc or ScView, depending on whether the
function is a func or a view.

The ScFuncs struct provides a member function for each func or view that will create their
respective function descriptor, initialize it properly, and returns it.

In the next section we will look at how to use function descriptors to
[call a smart contract function synchronously](call.mdx).
